<template>
  <div>
    <Table
      class="app-songs-table"
      :columns="columns"
      :data="songs"
    />
    <div style="margin: 10px;overflow: hidden">
      <div style="float: right;">
        <Page
          v-if="res.pageCount > 1"
          :total="res.pageCount"
          :current="res.page"
          size="small"
          @on-change="changePage"
        />
      </div>
    </div>
  </div>
</template>

<script lang="tsx">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
import { MarkRequired } from 'ts-essentials'
import { CreateQueryParams } from '@nestjsx/crud-request'
import { TableColumn } from 'view-design'
import { CrudPaginatedRes, getDefaultCrudPaginatedRes } from '@/api'
import { Song, getSongs } from '@/api/resources'
import { formateDurationOfSong } from '@/utils'
import { VNode } from 'vue'

type RequiredSong = MarkRequired<Partial<Song>, 'id' | 'title' | 'duration' | 'belongsToArtists'>

@Component({
  name: 'SongsTable'
})
export default class extends Vue {
  @Prop() userId!: number
  @Prop() playListId!: number;
  private res: CrudPaginatedRes<RequiredSong> = getDefaultCrudPaginatedRes()
  private page = 1

  get params (): CreateQueryParams {
    return this.playListId > 0
      ? {
        search: { 'inPlayLists.id': this.playListId },
        join: [
          { field: 'inPlayLists', select: ['id'] },
          { field: 'belongsToArtists', select: ['id', 'name'] }
        ],
        page: this.page
      }
      : {
        search: {
          'favByUsers.id': this.userId
        },
        join: [
          { field: 'favByUsers', select: ['id'] },
          { field: 'belongsToArtists', select: ['id', 'name'] }
        ],
        page: this.page
      }
  }

  get songs (): RequiredSong[] {
    return this.res.data
  }

  private columns: TableColumn[] = [
    {
      title: '歌名',
      key: 'title',
      align: 'center',
      render: (h, p) => {
        return (
          <router-link to={{ name: 'LibrarySong', params: { songId: (p?.row as RequiredSong)?.id } }}>
            {(p?.row as RequiredSong)?.title}
          </router-link>
        )
      }
    },
    {
      title: '歌手',
      key: 'artist',
      align: 'center',
      render: (h, p) => {
        const doms: VNode[] = [];
        (p?.row as RequiredSong).belongsToArtists.forEach((artist) => {
          const v = (
            <router-link to={{ name: 'LibraryArtist', params: { artistId: artist.id } }}>
              {artist.name}
            </router-link>
          )
          doms.push(v)
        })
        return <div>{doms}</div>
      }
    },
    {
      title: '时长',
      key: 'duration',
      align: 'center',
      render: (h, p) => {
        return <span>{formateDurationOfSong((p?.row as RequiredSong)?.duration)}</span>
      }
    }
  ];

  async mounted () {
    this.updateData()
  }

  @Watch('userId')
  private handleUserIdUpdate (id: number) {
    this.updateData()
  }

  @Watch('playListId')
  private handlePlayListIdUpdate (id: number) {
    this.updateData()
  }

  private async updateData () {
    if (typeof this.playListId !== 'number' || typeof this.userId !== 'number') return

    const { data } = await getSongs(this.params)
    this.res = data as CrudPaginatedRes<Song>
  }

  private changePage (page: number) {
    this.page = page
    this.updateData()
  }
}
</script>

<style lang="less" scoped>
@import "../../../styles/theme";
.app-songs-table {
  &/deep/.ivu-table {
    * {
      background-color: @dark-bg-color;
    }
  }
  &/deep/a {
    &:hover {
      color: @text-color;
    }
    &::after {
      content: ' / ';
    }
    &:last-of-type {
      &::after {
        content: none;
      }
    }
  }
}
</style>
